package br.ufpe.cin.camid.core.lifecycle;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import br.ufpe.cin.camid.core.lifecycle.factory.ManagedObjectFactory;
import br.ufpe.cin.camid.core.objects.ManagedObjectHandler;
import br.ufpe.cin.camid.core.objects.NonBlockingAcquireStrategy;

import com.google.inject.Inject;
import com.google.inject.Singleton;

@Singleton
public class StatelessObjectManager implements ObjectManager 
{
	
	private ObjectRegistry registry;
	
	private ManagedObjectFactory factory;
	
	private Map<String, String> statelessObjectAliasMap;
	
	@Inject
	public StatelessObjectManager(ObjectRegistry registry, ManagedObjectFactory factory)
	{
		this.registry = registry;
		this.factory = factory;
		this.statelessObjectAliasMap = new HashMap<String,String> ();
	}
	
	
	/* (non-Javadoc)
	 * @see br.ufpe.cin.camid.core.lifecycle.ObjectManager#create(java.lang.String, java.lang.Class)
	 */
	@Override
	public ManagedObjectHandler create(String objectId, Class<?> concreteClass)
	{
		ManagedObjectHandler createdHandler = null;
		Collection<ManagedObjectHandler> handlers = registry.findByDefinition(concreteClass);
		if(handlers.isEmpty())
		{
			createdHandler = factory.createObjectHandlerFromDefinition(objectId, concreteClass, new NonBlockingAcquireStrategy());
			registry.add(createdHandler);
		}
		else
		{
			for(ManagedObjectHandler handler : handlers)
			{
				createdHandler = handler;
				break;
			}
		}
		
		statelessObjectAliasMap.put(objectId, createdHandler.getId());
		return createdHandler;
	}

	/* (non-Javadoc)
	 * @see br.ufpe.cin.camid.core.lifecycle.ObjectManager#find(java.lang.String)
	 */
	@Override
	public ManagedObjectHandler find(String objectId) 
	{
		String concreteObjectId = statelessObjectAliasMap.get(objectId);
		ManagedObjectHandler handler = registry.find(concreteObjectId);
		return handler;
	}


	/* (non-Javadoc)
	 * @see br.ufpe.cin.camid.core.lifecycle.ObjectManager#remove(java.lang.String)
	 */
	@Override
	public ManagedObjectHandler remove(String objectId) {
		ManagedObjectHandler handler = this.find(objectId);
		statelessObjectAliasMap.remove(objectId);
		return handler;
	}


	/* (non-Javadoc)
	 * @see br.ufpe.cin.camid.core.lifecycle.ObjectManager#insert(br.ufpe.cin.camid.core.lifecycle.ManagedObjectHandler)
	 */
	@Override
	public ManagedObjectHandler insert(String objectId, Object object) 
	{
		return this.create(objectId, object.getClass());
	}
	
}
